import axios, {
  AxiosError,
  type AxiosRequestConfig,
  type AxiosResponse,
  type InternalAxiosRequestConfig,
} from "axios";
import { ElMessage } from "element-plus";
import { getMessageInfo } from "./status";
import { useUserStore } from "@/stores/user";
import { storeToRefs } from "pinia";

// 基础响应数据结构
interface BaseResponse<T = any> {
  message: string;
  code: number | string;
  data: T;
  status?: number;
}

const service = axios.create({
  baseURL: Boolean(Number(import.meta.env.VITE_APP_USE_MOCK))
    ? import.meta.env.VITE_APP_MOCK_BASEURL
    : import.meta.env.VITE_APP_API_BASEURL,
  timeout: 5000,
});

// 请求拦截
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const { token } = storeToRefs(useUserStore());
    // 请求头 token
    if (token.value) {
      config.headers.Authorization = token.value;
    }

    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  },
);

// 响应拦截
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const { data } = response;

    if (response.status === 200 && data.status === 200) {
      return response;
    }

    ElMessage({
      message: getMessageInfo(data.status),
      type: "error",
    });

    return response;
  },
  // 请求失败
  (error) => {
    const { response } = error;
    if (response) {
      ElMessage({
        message: getMessageInfo(response.status),
        type: "error",
      });
    } else {
      ElMessage({
        message: "网络错误",
        type: "error",
      });
    }
  },
);

// 此处相当于二次响应拦截
// 为响应数据进行定制化处理
const requestInstance = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  const conf = config;
  return new Promise((resolve, reject) => {
    service
      .request<any, AxiosResponse<BaseResponse>>(conf)
      .then((res: AxiosResponse<BaseResponse>) => {
        const data = res.data;
        // 如果data.code为错误代码返回message信息
        if (data.status != 200) {
          ElMessage({
            message: data.message,
            type: "error",
          });
          reject(data.message);
        } else {
          // ElMessage({
          //   message: data.message,
          //   type: "success",
          // });
          // 此处返回data信息 也就是 api 中配置好的 Response类型
          resolve(data as T);
        }
      });
  });
};

// 在最后使用封装过的axios导出不同的请求方式
export function get<T = any, U = any>(
  config: AxiosRequestConfig,
  url: string,
  parms?: U,
): Promise<T> {
  return requestInstance({ ...config, url, method: "GET", params: parms });
}

export function post<T = any, U = any>(
  config: AxiosRequestConfig,
  url: string,
  data: U,
): Promise<T> {
  return requestInstance({ ...config, url, method: "POST", data: data });
}
